/**
 * 
 */
package com.googlecode.pcapj.bridj;

import org.bridj.BridJ;
import org.bridj.CRuntime;
import org.bridj.Callback;
import org.bridj.Pointer;
import org.bridj.ann.Library;
import org.bridj.ann.Runtime;

/**
 * 
 */
@Library("wpcap") 
@Runtime(CRuntime.class)
public class Wpcap {
	static {
		BridJ.register();
	}

	public static final int AF_INET = 2;               /* internetwork: UDP, TCP, etc. */
	public static final int AF_INET6 = 23;              /* IPv6 */
	
	/**
	 * Defines if the adapter has to go in promiscuous mode.
	 */
	public static final int PCAP_OPENFLAG_PROMISCUOUS = 1; 
	   
	/**
	 * Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol.  
	 */
	public static final int PCAP_OPENFLAG_DATATX_UDP = 2;
	
	/**
	 * Defines if the remote probe will capture its own generated traffic.
	 */
	public static final int PCAP_OPENFLAG_NOCAPTURE_RPCAP = 4;

	/**
	 * Defines if the local adapter will capture its own generated traffic. 
	 */
	public static final int PCAP_OPENFLAG_NOCAPTURE_LOCAL = 8; 
	   
	/**
	 * This flag configures the adapter for maximum responsiveness.
	 */
	public static final int PCAP_OPENFLAG_MAX_RESPONSIVENESS = 16; 
	   
	/**
	 * Size to use when allocating the buffer that contains the libpcap errors.<br/>
	 * Definition at line 59 of file incs/pcap.h.
	 */
	public static final int PCAP_ERRBUF_SIZE = 256;
	
	public static final int PCAP_BUF_SIZE = 1024;
	
	public static final int PCAP_SRC_FILE = 2;

	public static final int PCAP_SRC_IFLOCAL = 3;

	public static final int PCAP_SRC_IFREMOTE = 4;
	
	public static final int PCAP_IF_LOOPBACK = 0x00000001;	/* interface is loopback */
	
	/**
	 * String that will be used to determine the type of source in use (file, remote/local interface).
	 * This string will be prepended to the interface name in order to create a string that contains all the information required to open the source.
	 * This string indicates that the user wants to open a capture from a network interface. This string does not necessarily involve the use of the RPCAP protocol. If the interface required resides on the local host, the RPCAP protocol is not involved and the local functions are used.
	 * Definition at line 177 of file remote-ext.h.
	 */
	public static final Pointer<Byte> PCAP_SRC_IF_STRING = Pointer.pointerToCString("rpcap://");
	
	public static final Pointer<Byte> PCAP_SRC_FILE_STRING = Pointer.pointerToCString("file://");
	
	public static abstract class packet_handler extends Callback<packet_handler> {
		public abstract void handle(Pointer<Byte> param, Pointer<pcap_pkthdr> header, Pointer<Byte> pkt_data);
	}; 
	  
	/**
	 * @param source
	 * @param auth
	 * @param alldevs
	 * @param errbuf
	 * @return
	 */
	public native static int pcap_findalldevs_ex(Pointer<Byte> source, Pointer<?> auth, Pointer<Pointer<pcap_if>> alldevs, Pointer<Byte> errbuf);
	
	public native static void pcap_freealldevs  (Pointer<pcap_if> alldevsp);
	
	public native static Pointer<?> pcap_open(Pointer<Byte> source, int snaplen, int flags, int read_timeout, Pointer<?> auth, Pointer<Byte> errbuf);
	
	public native static void pcap_close(Pointer<?>  p);
	
	public native static int pcap_loop(Pointer<?> p, int cnt, Pointer<packet_handler> callback, Pointer<Byte> user);
	public native static int pcap_breakloop(Pointer<?> p);	  
	/**
	 * 
	 * @param p
	 * @param pkt_header
	 * @param pkt_data
	 * @return
	 *  1 if the packet has been read without problems
	 *  0 if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data don't point to a valid packet
	 *  -1 if an error occurred
	 *  -2 if EOF was reached reading from an offline capture
	 */
	public native static int pcap_next_ex(Pointer<?> p, Pointer<Pointer<pcap_pkthdr>> pkt_header, Pointer<Pointer<Byte>> pkt_data); 
	
	public native static int pcap_datalink(Pointer<?> p);  
	
	public native static int pcap_compile(Pointer<?> p, Pointer<bpf_program> fp, Pointer<Byte> str, int  optimize, int netmask); 

	public native static int pcap_setfilter(Pointer<?> p, Pointer<bpf_program> fp); 
	
	public native static Pointer<Byte> pcap_dump_open(Pointer<?> p, Pointer<Byte> fname); 

	public native static void pcap_dump_close (Pointer<?> dumper);  
	
	public native static void pcap_dump(Pointer<?> pcap_dumper, Pointer<pcap_pkthdr> h, Pointer<Byte> sp); 

	public native static int pcap_createsrcstr  (Pointer<Byte> source, int type, Pointer<Byte> host, Pointer<Byte> port, Pointer<Byte> name, Pointer<Byte> errbuf); 
	
	public native static Pointer<Byte> pcap_geterr(Pointer<?> p);  
}
